import numpy as np
import matplotlib.pyplot as plt


def line_intersection(line1, line2):
    x1, y1, x2, y2 = line1
    x3, y3, x4, y4 = line2
    A1 = y2 - y1
    B1 = x1 - x2
    C1 = x1 * y2 - x2 * y1
    A2 = y4 - y3
    B2 = x3 - x4
    C2 = x3 * y4 - x4 * y3
    det = A1 * B2 - A2 * B1
    if det == 0:
        return None  # 平行线
    else:
        x = (B2 * C1 - B1 * C2) / det
        y = (A1 * C2 - A2 * C1) / det
        return x, y


def calculate_all_tangent_lines(centers, radius):
    # 输入参数和返回定义与原始代码相同
    # intersection_points = []
    intersection_points_outside = []
    intersection_points_inside = []
    for i in range(1, len(centers) - 1):
        x1, y1 = centers[i - 1]
        x2, y2 = centers[i]
        x3, y3 = centers[i + 1]

        # 计算切线与圆心连线的夹角
        angle1 = np.arctan2(y2 - y1, x2 - x1)
        angle2 = np.arctan2(y3 - y2, x3 - x2)

        # 计算切线的斜率
        slope1 = angle1
        slope2 = angle2

        x_t1_up = x1 + radius * np.sin(slope1)
        y_t1_up = y1 - radius * np.cos(slope1)
        x_t2_up = x2 + radius * np.sin(slope1)
        y_t2_up = y2 - radius * np.cos(slope1)

        x_t1_down = x1 - radius * np.sin(slope1)
        y_t1_down = y1 + radius * np.cos(slope1)
        x_t2_down = x2 - radius * np.sin(slope1)
        y_t2_down = y2 + radius * np.cos(slope1)

        # 计算第二个圆与第三个圆的切线点
        x_t3_up = x2 + radius * np.sin(slope2)
        y_t3_up = y2 - radius * np.cos(slope2)
        x_t4_up = x3 + radius * np.sin(slope2)
        y_t4_up = y3 - radius * np.cos(slope2)

        x_t3_down = x2 - radius * np.sin(slope2)
        y_t3_down = y2 + radius * np.cos(slope2)
        x_t4_down = x3 - radius * np.sin(slope2)
        y_t4_down = y3 + radius * np.cos(slope2)

        # 检查切线是否平行
        if abs(slope1 - slope2) > 1e-6:  # 不平行
            intersection = line_intersection((x_t1_up, y_t1_up, x_t2_up, y_t2_up), (x_t3_up, y_t3_up, x_t4_up, y_t4_up))
            if intersection is not None:
                intersection_points.append(intersection)
            intersection = line_intersection((x_t1_down, y_t1_down, x_t2_down, y_t2_down),
                                             (x_t3_down, y_t3_down, x_t4_down, y_t4_down))
            if intersection is not None:
                intersection_points.append(intersection)
        else:
            # 两条切线平行，需要计算中间圆与切线的两个交点
            intersection1 = (x2 + radius * np.sin(slope1), y2 - radius * np.cos(slope1))
            intersection2 = (x2 - radius * np.sin(slope1), y2 + radius * np.cos(slope1))
            intersection_points.append(intersection1)
            intersection_points.append(intersection2)
    # 新增：去除过于接近原始点的交点
    filtered_intersection_points = []
    for point in intersection_points:
        if all(np.linalg.norm(np.array(point) - np.array(center)) >= radius for center in centers):
            filtered_intersection_points.append(point)

    return filtered_intersection_points

def add_inbetween_points(points, density):
    
    # 在点之间按照给定密度补点的函数
    new_points = []
    for i in range(len(points) - 1):
        new_points.append(points[i])
        # 将元组转换为NumPy数组以便进行计算
        point1 = np.array(points[i])
        point2 = np.array(points[i+1])
        dist = np.linalg.norm(point2 - point1)
        if dist > density:
            # 计算应该补充多少点
            num_points_to_add = int(np.ceil(dist / density)) - 1
            for j in range(1, num_points_to_add + 1):
                # 在NumPy数组之间进行运算
                new_point = point1 + (point2 - point1) * (j / (num_points_to_add + 1))
                # 将计算结果转换回元组，以保持与原始数据类型一致
                new_points.append(tuple(new_point))
    new_points.append(points[-1])  # 添加最后一个点
    return new_points

# 以下是使用您的数据和新函数的代码
data = [
    (-6.522553, 5.020428),
    (-6.472553, 5.019595),
    (-6.422553, 5.018761),
    (-6.372553, 5.017928),
    (-6.322553, 5.017095),
    (-6.272553, 5.016261),
    (-6.222553, 5.015428),
    (-6.172553, 5.014595),
    (-6.122553, 5.013762),
    (-6.072553, 5.012928),
    (-6.022553, 5.012094),
    (-5.972553, 5.011261),
    (-5.922553, 5.010428),
    (-5.872553, 5.009594),
    (-5.822553, 5.008761),
    (-5.772553, 5.007928),
    (-5.722553, 5.007094),
    (-5.672553, 5.006261),
    (-5.622553, 5.005428),
    (-5.572553, 5.004595),
    (-5.522553, 5.003761),
    (-5.472553, 5.002928),
    (-5.422553, 5.002095),
    (-5.372553, 5.001261),
    (-5.322553, 5.000428),
    (-5.272553, 4.999595),
    (-5.222553, 4.998761),
    (-5.172553, 4.997928),
    (-5.122553, 4.997095),
    (-5.072553, 4.996261),
    (-5.022553, 4.995428),
    (-4.972553, 4.994595),
    (-4.922553, 4.993761),
    (-4.872553, 4.992928),
    (-4.822553, 4.992095),
    (-4.772553, 4.991261),
    (-4.722553, 4.990428),
    (-4.672553, 4.989594),
    (-4.622553, 4.988761),
    (-4.572553, 4.987928),
    (-4.522553, 4.987094),
    (-4.472553, 4.986261),
    (-4.422553, 4.985428),
    (-4.372553, 4.984594),
    (-4.322553, 4.983761),
    (-4.272553, 4.982928),
    (-4.222553, 4.982095),
    (-4.172553, 4.981261),
    (-4.122553, 4.980428),
    (-4.072553, 4.979595),
    (-4.022553, 4.978761),
    (-3.972553, 4.977928),
    (-3.922553, 4.977095),
    (-3.872553, 4.976261),
    (-3.822553, 4.975428),
    (-3.772553, 4.974595),
    (-3.722553, 4.973761),
    (-3.672553, 4.972928),
    (-3.622553, 4.972095),
    (-3.572553, 4.971261),
    (-3.522553, 4.970428),
    (-3.472553, 4.969594),
    (-3.422553, 4.968761),
    (-3.372553, 4.967928),
    (-3.322553, 4.967094),
    (-3.272553, 4.966261),
    (-3.222553, 4.965428),
    (-3.172553, 4.964594),
    (-3.122553, 4.963761),
    (-3.072553, 4.962928),
    (-3.022553, 4.962094),
    (-2.972553, 4.961261),
    (-2.922553, 4.960428),
    (-2.872553, 4.959595),
    (-2.822553, 4.958761),
    (-2.772553, 4.957928),
    (-2.722553, 4.957095),
    (-2.672553, 4.956261),
    (-2.622553, 4.955428),
    (-2.572553, 4.954595),
    (-2.522553, 4.953761),
    (-2.472553, 4.952928),
    (-2.422553, 4.952095),
    (-2.372553, 4.951261),
    (-2.322553, 4.950428),
    (-2.272553, 4.949594),
    (-2.222553, 4.948761),
    (-2.172553, 4.947928),
    (-2.122553, 4.947094),
    (-2.072553, 4.946261),
    (-2.022553, 4.945428),
    (-1.972553, 4.944594),
    (-1.922553, 4.943761),
    (-1.872553, 4.942928),
    (-1.822553, 4.942094),
    (-1.772553, 4.941261),
    (-1.722553, 4.940428),
    (-1.672553, 4.939594),
    (-1.622553, 4.938761),
    (-1.601192, 4.938406),
    (-1.602730, 4.888405),
    (-1.604269, 4.838406),
    (-1.605807, 4.788405),
    (-1.607346, 4.738406),
    (-1.608884, 4.688406),
    (-1.610423, 4.638405),
    (-1.611961, 4.588406),
    (-1.613500, 4.538405),
    (-1.615038, 4.488406),
    (-1.616577, 4.438406),
    (-1.618115, 4.388405),
    (-1.619653, 4.338406),
    (-1.621192, 4.288405),
    (-1.622730, 4.238406),
    (-1.624269, 4.188406),
    (-1.625807, 4.138405),
    (-1.627346, 4.088406),
    (-1.628884, 4.038405),
    (-1.630423, 3.988405),
    (-1.631961, 3.938406),
    (-1.633500, 3.888406),
    (-1.635038, 3.838406),
    (-1.636577, 3.788405),
    (-1.638115, 3.738405),
    (-1.639653, 3.688406),
    (-1.641192, 3.638406),
    (-1.642730, 3.588406),
    (-1.644269, 3.538405),
    (-1.645807, 3.488405),
    (-1.647346, 3.438406),
    (-1.648884, 3.388406),
    (-1.650423, 3.338406),
    (-1.651961, 3.288405),
    (-1.653500, 3.238405),
    (-1.655038, 3.188406),
    (-1.656577, 3.138406),
    (-1.658115, 3.088406),
    (-1.659653, 3.038405),
    (-1.661192, 2.988405),
    (-1.662730, 2.938406),
    (-1.664269, 2.888406),
    (-1.665807, 2.838406),
    (-1.667346, 2.788405),
    (-1.668884, 2.738405),
    (-1.670423, 2.688406),
    (-1.671961, 2.638406),
    (-1.673500, 2.588406),
    (-1.675038, 2.538405),
    (-1.676576, 2.488405),
    (-1.678115, 2.438406),
    (-1.679654, 2.388406),
    (-1.681192, 2.338406),
    (-1.682730, 2.288405),
    (-1.684269, 2.238405),
    (-1.685807, 2.188406),
    (-1.687346, 2.138406),
    (-1.688884, 2.088406),
    (-1.690423, 2.038405),
    (-1.691961, 1.988405),
    (-1.693500, 1.938406),
    (-1.695038, 1.888406),
    (-1.696577, 1.838405),
    (-1.698115, 1.788406),
    (-1.699654, 1.738405),
    (-1.701192, 1.688406),
    (-1.702730, 1.638406),
    (-1.704269, 1.588405),
    (-1.705807, 1.538406),
    (-1.707346, 1.488405),
    (-1.708884, 1.438406),
    (-1.710423, 1.388406),
    (-1.711961, 1.338405),
    (-1.713500, 1.288406),
    (-1.715038, 1.238405),
    (-1.716577, 1.188406),
    (-1.718115, 1.138406),
    (-1.719653, 1.088405),
    (-1.721192, 1.038406),
    (-1.722730, 0.988406),
    (-1.724269, 0.938406),
    (-1.725807, 0.888406),
    (-1.727346, 0.838405),
    (-1.728884, 0.788406),
    (-1.730423, 0.738406),
    (-1.731961, 0.688406),
    (-1.733500, 0.638406),
    (-1.735038, 0.588405),
    (-1.736577, 0.538406),
    (-1.738115, 0.488406),
    (-1.739653, 0.438406),
    (-1.741192, 0.388406),
    (-1.742730, 0.338406),
    (-1.744269, 0.288406),
    (-1.745807, 0.238406),
    (-1.747346, 0.188406),
    (-1.748884, 0.138406),
    (-1.750423, 0.088406),
    (-1.751961, 0.038406),
    (-1.753500, -0.011594),
    (-1.755038, -0.061594),
    (-1.756577, -0.111594),
    (-1.758115, -0.161594),
    (-1.759653, -0.211594),
    (-1.761192, -0.261594),
    (-1.762730, -0.311594),
    (-1.764269, -0.361594)
]


intersection_points = calculate_all_tangent_lines(data, 1)

# 计算原始点之间的平均距离，用作补点的密度
distances = [np.linalg.norm(np.array(data[i+1]) - np.array(data[i])) for i in range(len(data) - 1)]
average_distance = np.mean(distances)

# 分割为外圈和内圈
outside_result = [intersection_points[i] for i in range(1, len(intersection_points), 2)]
inside_result = [intersection_points[i] for i in range(0, len(intersection_points), 2)]

# 对外圈和内圈进行补点
# outside_result = add_inbetween_points(outside_result, average_distance)
# inside_result = add_inbetween_points(inside_result, average_distance)

# 下面的代码绘制结果，与原代码相同...
# 绘制原始点
original_x, original_y = zip(*data)
plt.scatter(original_x, original_y, c='b', label='Original Points', marker='.', s=5)

# 绘制计算得到的点
intersection_x, intersection_y = zip(*outside_result)
plt.scatter(intersection_x, intersection_y, c='r', label='outside_result Points', marker='.', s=5)


intersection_x, intersection_y = zip(*inside_result)
plt.scatter(intersection_x, intersection_y, c='g', label='inside_result Points', marker='.', s=5)
plt.legend()
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True)
plt.show()
